package com.example.servlet.auth;

import com.example.entity.*;
import com.example.service.FlightService;
import com.example.service.InitService;
import com.example.service.UserService;
import com.example.service.impl.FlightServiceImpl;
import com.example.service.impl.InitServiceImpl;
import com.example.service.impl.UserServiceImpl;
import com.example.utils.BCryptUtil;
import com.example.utils.MybatisUtil;
import com.example.utils.ThymeleafUtil;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.ibatis.session.SqlSession;
import org.thymeleaf.context.Context;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@WebServlet("/host")
public class HostServlet extends HttpServlet {
    private InitService service;
    private SqlSession sqlSession;

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        sqlSession = MybatisUtil.getSession();
        service = new InitServiceImpl(sqlSession);
    }

    @Override
    public void destroy() {
        sqlSession.close();
        super.destroy();
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        if (cookies != null) {
            String u_account = null;
            String u_password = null;
            String m_account = null;
            String m_password = null;
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("u_account")) u_account = cookie.getValue();
                if (cookie.getName().equals("u_password")) u_password = cookie.getValue();
                if (cookie.getName().equals("m_account")) m_account = cookie.getValue();
                if (cookie.getName().equals("m_password")) m_password = cookie.getValue();
            }
            if (u_account != null && u_password != null) {
                String storedHashedPassword = service.getHashedPasswordByAccount(u_account);
                if(storedHashedPassword != null){
                    boolean isPasswordCorrect = BCryptUtil.verifyPassword(u_password, storedHashedPassword);
                    if(isPasswordCorrect){
                        // 登录校验
                        if (service.userAuth(u_account, storedHashedPassword, req.getSession())) {
                            resp.sendRedirect("user_index");
                            return;
                        }
                    }
                }
            }
            if(m_account != null && m_password != null){
                if (service.managerAuth(m_account, m_password, req.getSession())) {
                    resp.sendRedirect("manager_index1");
                    return;
                }
            }
        }
        Context context = new Context();
        List<String> top4ArrivalCities = service.getTop4ArrivalCities();
        List<String> top4DepartureCities = service.getTop4DepartureCities();
        List<String> From = new ArrayList<>();
        List<String> To = new ArrayList<>();
        int city_count=0;
        Random random = new Random();
        Set<String> pairSet = new HashSet<>();
        while(true){
            int index1 = random.nextInt(4);
            int index2 = random.nextInt(4);
            String from = top4DepartureCities.get(index1);
            String to = top4ArrivalCities.get(index2);
            String pair = from + "->" + to;
            if(from.equals(to)) continue;
            if (!pairSet.contains(pair)) {
                pairSet.add(pair);
                From.add(from);
                To.add(to);
                city_count++;
            }
            if(city_count>=3) break;
        }
        LocalDate today = LocalDate.now();  // 获取当前日期
        LocalDate tomorrow = today.plusDays(1);  // 获取明天日期
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");  // 定义格式
        String tomorrowStr = tomorrow.format(formatter);  // 格式化输出
        List<Flight> flights = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            String from = From.get(i);
            String to = To.get(i);
            flights.add(service.searchCheapestFlight(from, to, tomorrowStr));
        }
        context.setVariable("flights", flights);

        String destination1 = top4ArrivalCities.get(0);
        String destination2 = top4ArrivalCities.get(1);
        String destination3 = top4ArrivalCities.get(2);
        String destination4 = top4ArrivalCities.get(3);
        int randomNum1 = new Random().nextInt(3) + 1; // 生成 1~3 的随机数
        int randomNum2 = new Random().nextInt(3) + 1;
        int randomNum3 = new Random().nextInt(3) + 1;
        int randomNum4 = new Random().nextInt(3) + 1;
        context.setVariable("Destination1Num", destination1 + randomNum1);
        context.setVariable("Destination2Num", destination2 + randomNum2);
        context.setVariable("Destination3Num", destination3 + randomNum3);
        context.setVariable("Destination4Num", destination4 + randomNum4);
        context.setVariable("Destination1", destination1);
        context.setVariable("Destination2", destination2);
        context.setVariable("Destination3", destination3);
        context.setVariable("Destination4", destination4);
        //初始化
        try{
            LocalDate todayDate = LocalDate.now();
            LocalTime currentTime = LocalTime.now();
            DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
            String todayStr = todayDate.format(dateFormatter);
            String timeStr = currentTime.format(timeFormatter);
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String dateTimeStr = now.format(dateTimeFormatter);
            //航班状态
            List<Flight> flightList = service.getFlightList(todayStr);
            for (Flight flight : flightList) {
                FlightStatus  flightStatus = service.getFlightStatusById(flight.getF_id());
                if(flightStatus.getStatus().equals("计划中")){
                    if(flight.getDeparture_time().compareTo(timeStr) > 0){
                        //即将起飞
                        if(service.updateFlightStatus("即将起飞", flight.getF_id())==0){
                            throw new Exception("Failed to update flight status");
                        }
                    }else{
                        //已起飞
                        if(flight.getArrival_time().compareTo(timeStr) > 0){
                            if(service.updateFlightStatus("已起飞", flight.getF_id())==0){
                                throw new Exception("Failed to update flight status");
                            }
                        }
                        else{
                            //已到达
                            if(service.updateFlightStatus("已到达", flight.getF_id())==0){
                                throw new Exception("Failed to update flight status");
                            }
                        }
                    }
                } else if (flightStatus.getStatus().equals("即将起飞")) {
                    if(flight.getDeparture_time().compareTo(timeStr) <= 0){
                        if(flight.getArrival_time().compareTo(timeStr) > 0){
                            //已起飞
                            if(service.updateFlightStatus("已起飞", flight.getF_id())==0){
                                throw new Exception("Failed to update flight status");
                            }
                        }
                        else{
                            //已到达
                            if(service.updateFlightStatus("已到达", flight.getF_id())==0){
                                throw new Exception("Failed to update flight status");
                            }
                        }
                    }
                }else{
                    if(flight.getArrival_time().compareTo(timeStr) <= 0){
                        //已到达
                        if(service.updateFlightStatus("已到达", flight.getF_id())==0){
                            throw new Exception("Failed to update flight status");
                        }
                    }
                }
            }
            //机票状态
            List<Ticket> ticketList = service.getTicketList();
            for (Ticket ticket : ticketList) {
                if(ticket.getStatus().equals("即将起飞")){
                    if(ticket.getDate().compareTo(timeStr) <= 0){
                        //已完成
                        if(service.updateTicketStatus(ticket.getId())==0){
                            throw new Exception("Failed to update ticket status");
                        }
                        //里程
                        Flight flight = service.getFlightById(ticket.getFlightNo());
                        Passenger passenger = service.getPassengerById(ticket.getPassenger_id());
                        if(passenger.getMileage()<2500){
                            if(service.updateMileage(ticket.getPassenger_id(), flight.getDistance())==0){
                                throw new Exception("Failed to update passenger mileage");
                            }
                        } else if (passenger.getMileage()<10000) {
                            if(service.updateMileage(ticket.getPassenger_id(), flight.getDistance()*1.15)==0){
                                throw new Exception("Failed to update passenger mileage");
                            }
                        } else if (passenger.getMileage()<25000) {
                            if(service.updateMileage(ticket.getPassenger_id(), flight.getDistance()*1.25)==0){
                                throw new Exception("Failed to update passenger mileage");
                            }
                        } else {
                            if(service.updateMileage(ticket.getPassenger_id(), flight.getDistance()*1.5)==0){
                                throw new Exception("Failed to update passenger mileage");
                            }
                        }
                        if(service.isUserExist(passenger.getID_type(), passenger.getPassenger_ID_card())==1){
                            if(passenger.getMileage()<2500){
                                if(service.updateGrade("普通会员", passenger.getID_type(), passenger.getPassenger_ID_card())==0){
                                    throw new Exception("Failed to update passenger grade");
                                }
                            } else if (passenger.getMileage()<10000) {
                                if(service.updateGrade("黄金会员", passenger.getID_type(), passenger.getPassenger_ID_card())==0){
                                    throw new Exception("Failed to update passenger grade");
                                }
                            } else if (passenger.getMileage()<25000) {
                                if(service.updateGrade("白金会员", passenger.getID_type(), passenger.getPassenger_ID_card())==0){
                                    throw new Exception("Failed to update passenger grade");
                                }
                            } else {
                                if(service.updateGrade("钻石会员", passenger.getID_type(), passenger.getPassenger_ID_card())==0){
                                    throw new Exception("Failed to update passenger grade");
                                }
                            }
                        }
                    }
                }
            }
            //订单状态
            List<Order> orderList = service.getOrderList(todayStr);
            for (Order order : orderList) {
                Flight flight = service.getFlightById(order.getFlightNo());
                if(flight.getDeparture_date().compareTo(todayStr) <= 0){
                    if(service.updateOrderStatus(order.getId())==0){
                        throw new Exception("更新订单状态失败");
                    }
                }
            }
            //待支付
            List<Order> unpaidOrderList = service.getUnpaidOrderList();
            for (Order order : unpaidOrderList) {
                if(order.getPaymentDeadline().compareTo(dateTimeStr) > 0){
                    List<Ticket> ticketList1 = service.getTicketListByOrderId(order.getId());
                    for (Ticket ticket : ticketList1) {
                        if(Objects.equals(ticket.getSeat_type(), "经济舱")){
                            if(service.addEconomySpace(ticket.getFlightNo())==0){
                                throw new Exception("Failed to add economy space");
                            }
                        }else if (Objects.equals(ticket.getSeat_type(), "商务舱")){
                            if(service.addBusinessSpace(ticket.getFlightNo())==0){
                                throw new Exception("Failed to add business space");
                            }
                        }else {
                            if(service.addFirstSpace(ticket.getFlightNo())==0){
                                throw new Exception("Failed to add first space");
                            }
                        }
                        if(service.deleteTicket(ticket.getId())==0){
                            throw new Exception("Failed to delete ticket");
                        }
                    }
                    if(service.deleteOrder(order.getId())==0){
                        throw new Exception("Failed to delete order");
                    }
                }
            }
            service.commit();
        }catch (Exception e) {
            e.printStackTrace();
            service.rollback();
            req.getSession().setAttribute("unsubscribe_failure", new Object());
        }
        ThymeleafUtil.process("host.html", context, resp.getWriter());
    }
}
